"""
Grave! Important! Важно!

Proletoj el ĉiuj landoj, unuiĝu!
Workers of the world, unite!
Пролетарии всех стран, соединяйтесь!

https://tkom.pro
"""

from django.utils import timezone
from django.db import transaction
from django.utils.translation import gettext_lazy as _
import graphene
from graphene.types.generic import GenericScalar

from siriuso.utils import set_enhavo
from .schema import *
from ..models import *


class RedaktuEnketoTipo(graphene.Mutation):
    status = graphene.Boolean()
    message = graphene.String()
    enketo_tipo = graphene.Field(EnketoTipoNode, description=_('Созданная/изменённая запись типа Анкет'))

    class Arguments:
        uuid = graphene.UUID(description=_('UUID записи'))
        kodo = graphene.String(description=_('Код типа'))
        nomo = graphene.String(description=_('Название типа'))
        forigo = graphene.Boolean(description=_('Признак удаления записи'))
        arkivo = graphene.Boolean(description=_('Признак архивной записи'))
        publikigo = graphene.Boolean(description=_('Признак опубликованной записи'))

    @staticmethod
    def mutate(root, info, **kwargs):
        status = False
        message = None
        tipo = None
        uzanto = info.context.user

        if uzanto.is_authenticated:
            with transaction.atomic():
                # Создаём новую запись
                if not kwargs.get('uuid', False):
                    if uzanto.has_perm('enketo.povas_krei_enketo_tipon'):
                        # Проверяем наличие всех полей
                        if not kwargs.get('kodo', False):
                            message = '{} "{}"'.format(_('Не заполнено обязательное поле'), 'kodo')

                        # Проверяем наличие записи с таким кодом
                        try:
                            EnketoTipo.objects.get(kodo=kwargs.get('kodo'), forigo=False)
                            message = _('Запись с таим кодом уже существует')
                        except EnketoTipo.DoesNotExist:
                            pass

                        if kwargs.get('forigo', False) and not message:
                            message = '{} "{}"'.format(_('При создании записи не допустимо указание поля'), 'forigo')

                        if kwargs.get('arkivo', False) and not message:
                            message = '{} "{}"'.format(_('При создании записи не допустимо указание поля'), 'arkivo')

                        if not (kwargs.get('nomo', False) or message):
                            message = '{} "{}"'.format(_('Не заполнено обязательное поле'), 'nomo')

                        if not message:
                            tipo = EnketoTipo.objects.create(
                                kodo=kwargs.get('kodo'),
                                speciala=False,
                                forigo=False,
                                arkivo=False,
                                publikigo=kwargs.get('publikigo', False),
                                publikiga_dato=timezone.now()
                            )

                            set_enhavo(tipo.nomo, kwargs.get('nomo'), info.context.LANGUAGE_CODE)
                            tipo.save()

                            status = True
                            message = _('Запись создана')
                    else:
                        message = _('Недостаточно прав')
                else:
                    # Изменяем запись
                    if not (kwargs.get('kodo', False) or kwargs.get('nomo', False)
                            or kwargs.get('forigo', False) or kwargs.get('arkivo', False)
                            or kwargs.get('publikigo', False)):
                        message = _('Не задано ни одно поле для изменения')

                    if not message:
                        # Ищем запись для изменения
                        try:
                            tipo = EnketoTipo.objects.get(uuid=kwargs.get('uuid'), forigo=False)
                            if (not uzanto.has_perm('enketo.povas_forigi_tipon')
                                    and kwargs.get('forigo', False)):
                                message = _('Недостаточно прав для удаления')
                            elif not uzanto.has_perm('enketo.povas_shanghi_tipon'):
                                message = _('Недостаточно прав для изменения')
                            else:
                                tipo.kodo = kwargs.get('kodo', tipo.kodo)
                                tipo.forigo = kwargs.get('forigo', tipo.forigo)
                                tipo.foriga_dato = timezone.now() if kwargs.get('forigo', False) else None
                                tipo.arkivo = kwargs.get('arkivo', tipo.arkivo)
                                tipo.arkiva_dato = timezone.now() if kwargs.get('arkivo', False) else None
                                tipo.publikigo = kwargs.get('publikigo', tipo.publikigo)
                                tipo.publikiga_dato = timezone.now() if kwargs.get('publikigo', False) else None

                                if kwargs.get('nomo', False):
                                    set_enhavo(tipo.nomo, kwargs.get('nomo'), info.context.LANGUAGE_CODE)

                                tipo.save()
                                status = True
                                message = _('Запись успешно изменена')
                        except EnketoTipo.DoesNotExist:
                            message = _('Запись не найдена')
        else:
            message = _('Требуется авторизация')

        return RedaktuEnketoTipo(status=status, message=message, enketo_tipo=tipo)


class RedaktuEnketo(graphene.Mutation):
    status = graphene.Boolean()
    message = graphene.String()
    enketo = graphene.Field(EnketoNode, description=_('Созданная/изменённая Анкет'))

    class Arguments:
        uuid = graphene.UUID(description=_('UUID записи'))
        tipo_kodo = graphene.String(description=_('Код типа'))
        nomo = graphene.String(description=_('Название'))
        priskribo = graphene.String(description=_('Описание'))
        forigo = graphene.Boolean(description=_('Признак удаления записи'))
        arkivo = graphene.Boolean(description=_('Признак архивной записи'))
        publikigo = graphene.Boolean(description=_('Признак опубликованной записи'))
        # параметры для создания полей данной анкеты (используется только при создании новой анкеты)
        informoj_kvanto = graphene.Int(description=_('Количество полей')) # kvanto - численность - для последующей проверки
        informoj_nomo = graphene.List(graphene.String,description=_('Название полей'))
        informoj_priskribo = graphene.List(graphene.String,description=_('Описание полей'))
        informoj_tipo = graphene.List(graphene.String,description=_('Типы полей'))
        informoj_datumo = graphene.List(GenericScalar,description=_('Значение полей по умолчанию'))

    @staticmethod
    def mutate(root, info, **kwargs):
        status = False
        message = None
        enketo = None
        tipo = None
        uzanto = info.context.user

        if uzanto.is_authenticated:
            with transaction.atomic():
                # Создаём новую запись
                if not kwargs.get('uuid', False):
                    if uzanto.has_perm('enketo.povas_krei_enketo'):
                        # Проверяем наличие всех полей
                        if kwargs.get('forigo', False) and not message:
                            message = '{} "{}"'.format(_('При создании записи не допустимо указание поля'), 'forigo')

                        if kwargs.get('arkivo', False) and not message:
                            message = '{} "{}"'.format(_('При создании записи не допустимо указание поля'), 'arkivo')

                        # проверяем наличие полей анкеты
                        if kwargs.get('informoj_kvanto', False) and not message:
                            # проверяем наличие обязательных параметров
                            
                            # проверяем соответствия количества полей анкеты переданной численности
                            if not message:
                                if kwargs.get('informoj_nomo', False):
                                    if kwargs.get('informoj_kvanto') != len(kwargs.get('informoj_nomo')):
                                        message = '{} "{}"'.format(_('Не совпадает количество полей переданного количества с '), 'informoj_nomo')
                                else:
                                    message = '{} "{}"'.format(_('Не заполнено обязательное поле'), 'informoj_nomo')
                            if not message:
                                if kwargs.get('informoj_priskribo', False):
                                    if kwargs.get('informoj_kvanto') != len(kwargs.get('informoj_priskribo')):
                                        message = '{} "{}"'.format(_('Не совпадает количество полей переданного количества с '), 'informoj_priskribo')
                                else:
                                    message = '{} "{}"'.format(_('Не заполнено обязательное поле'), 'informoj_priskribo')
                            if not message:
                                if kwargs.get('informoj_tipo', False):
                                    if kwargs.get('informoj_kvanto') != len(kwargs.get('informoj_tipo')):
                                        message = '{} "{}"'.format(_('Не совпадает количество полей переданного количества с '), 'informoj_tipo')
                                    else:
                                        # Проверяем наличие записи с таким кодом
                                        for tipoj in kwargs.get('informoj_tipo'):
                                            if tipoj.lower() not in Informoj.tipo_choices_nomo:
                                                message='{} {} {}: {}'.format(_('Неверное значение поля -'), 'informoj_tipo.',
                                                    _('Допустимые значения'), Informoj.tipo_choices_nomo)
                                else:
                                    message = '{} "{}"'.format(_('Не заполнено обязательное поле'), 'informoj_tipo')
                            if not message:
                                if kwargs.get('informoj_datumo', False):
                                    if kwargs.get('informoj_kvanto') != len(kwargs.get('informoj_datumo')):
                                        message = '{} "{}"'.format(_('Не совпадает количество полей переданного количества с '), 'informoj_datumo')
                                else:
                                    message = '{} "{}"'.format(_('Не заполнено обязательное поле'), 'informoj_datumo')

                        if not message:
                            if not kwargs.get('tipo_kodo', False):
                                message = '{} "{}"'.format(_('Не заполнено обязательное поле'), 'tipo_kodo')
                            else:
                                try:
                                    tipo = EnketoTipo.objects.get(kodo=kwargs.get('tipo_kodo'), forigo=False,
                                                                        arkivo=False, publikigo=True)
                                except EnketoTipo.DoesNotExist:
                                    message = _('Неверный тип страницы')

                        if not (kwargs.get('priskribo', False) or message):
                            message = '{} "{}"'.format(_('Не заполнено обязательное поле'), 'priskribo')

                        if not (kwargs.get('nomo', False) or message):
                            message = '{} "{}"'.format(_('Не заполнено обязательное поле'), 'nomo')

                        if not message:
                            enketo = Enketo.objects.create(
                                autoro=uzanto,
                                tipo=tipo,
                                forigo=False,
                                arkivo=False,
                                publikigo=kwargs.get('publikigo', False),
                                publikiga_dato=timezone.now()
                            )

                            set_enhavo(enketo.nomo, kwargs.get('nomo'), info.context.LANGUAGE_CODE)
                            set_enhavo(enketo.priskribo, kwargs.get('priskribo'), info.context.LANGUAGE_CODE)
                            enketo.save()

                            # создаём поля анкеты
                            if kwargs.get('informoj_kvanto', False) and not message:
                                for i in range(kwargs.get('informoj_kvanto')):
                                    informoj = Informoj.objects.create(
                                        enketo=enketo,
                                        tipo=kwargs.get('informoj_tipo')[i].lower(),
                                        datumo=kwargs.get('informoj_datumo')[i],
                                        forigo=False,
                                        arkivo=False,
                                        publikigo=kwargs.get('publikigo', False),
                                        publikiga_dato=timezone.now()
                                    )

                                    set_enhavo(informoj.nomo, kwargs.get('informoj_nomo')[i], info.context.LANGUAGE_CODE)
                                    set_enhavo(informoj.priskribo, kwargs.get('informoj_priskribo')[i], info.context.LANGUAGE_CODE)

                                    informoj.save()

                            status = True
                            message = _('Запись создана')
                    else:
                        message = _('Недостаточно прав')
                else:
                    # Изменяем запись
                    if not (kwargs.get('priskribo', False) or kwargs.get('tipo_kodo', False)
                            or kwargs.get('nomo', False)
                            or kwargs.get('forigo', False) or kwargs.get('arkivo', False)
                            or kwargs.get('publikigo', False)):
                        message = _('Не задано ни одно поле для изменения')
                    if (kwargs.get('informoj_kvanto', False) or kwargs.get('informoj_nomo', False)
                            or kwargs.get('informoj_priskribo', False)
                            or kwargs.get('informoj_tipo', False) or kwargs.get('informoj_datumo', False)):
                        message = _('Записи полей анкеты в самой анкете править нельзя')

                    if 'tipo_kodo' in kwargs and not message:
                        try:
                            tipo = EnketoTipo.objects.get(kodo=kwargs.get('tipo_kodo'), forigo=False,
                                                                arkivo=False, publikigo=True)
                        except EnketoTipo.DoesNotExist:
                            message = _('Неверный тип')

                    # Ищем запись для изменения
                    if not message:
                        try:
                            enketo = Enketo.objects.get(uuid=kwargs.get('uuid'), forigo=False)
                            if (not uzanto.has_perm('enketo.povas_forigi_enketo')
                                    and kwargs.get('forigo', False)):
                                message = _('Недостаточно прав для удаления')
                            elif not uzanto.has_perm('enketo.povas_shanghi_enketo'):
                                message = _('Недостаточно прав для изменения')
                            else:

                                update_fields = [
                                    'tipo', 'forigo', 'foriga_dato', 'arkivo', 'arkiva_dato',
                                    'publikigo', 'publikiga_dato', 'lasta_autoro', 'lasta_dato',
                                ]

                                enketo.tipo = tipo or enketo.tipo
                                enketo.forigo = kwargs.get('forigo', enketo.forigo)
                                enketo.foriga_dato = timezone.now() if kwargs.get('forigo', False) else None
                                enketo.arkivo = kwargs.get('arkivo', enketo.arkivo)
                                enketo.arkiva_dato = timezone.now() if kwargs.get('arkivo', False) else None
                                enketo.publikigo = kwargs.get('publikigo', enketo.publikigo)
                                enketo.publikiga_dato = timezone.now() if kwargs.get('publikigo', False) else None
                                enketo.lasta_autoro = uzanto
                                enketo.lasta_dato = timezone.now()

                                if kwargs.get('priskribo', False):
                                    set_enhavo(enketo.priskribo, kwargs.get('priskribo'), info.context.LANGUAGE_CODE)
                                    update_fields.append('priskribo')

                                if kwargs.get('nomo', False):
                                    set_enhavo(enketo.nomo, kwargs.get('nomo'), info.context.LANGUAGE_CODE)
                                    update_fields.append('nomo')

                                enketo.save(update_fields=update_fields)
                                status = True
                                message = _('Запись успешно изменена')
                        except Enketo.DoesNotExist:
                            message = _('Запись не найдена')
        else:
            message = _('Требуется авторизация')

        return RedaktuEnketo(status=status, message=message, enketo=enketo)


class RedaktuInformoj(graphene.Mutation):
    status = graphene.Boolean()
    message = graphene.String()
    informoj = graphene.Field(InformojNode, description=_('Созданная/изменённая запись полей Анкеты'))

    class Arguments:
        uuid = graphene.UUID(description=_('UUID записи'))
        enketo_id = graphene.Int(description=_('ID анкеты'))
        nomo = graphene.String(description=_('Название'))
        priskribo = graphene.String(description=_('Описание'))
        tipo = graphene.String(description=_('Тип поля'))
        datumo = GenericScalar(description=_('Значение поля по умолчанию'))
        forigo = graphene.Boolean(description=_('Признак удаления записи'))
        arkivo = graphene.Boolean(description=_('Признак архивной записи'))
        publikigo = graphene.Boolean(description=_('Признак опубликованной записи'))

    @staticmethod
    def mutate(root, info, **kwargs):
        status = False
        message = None
        informoj = None
        enketo = None
        uzanto = info.context.user

        if uzanto.is_authenticated:
            with transaction.atomic():
                # Создаём новую запись
                if not kwargs.get('uuid', False):
                    if uzanto.has_perm('enketo.povas_krei_enketo_informoj'):
                        # Проверяем наличие обязательных полей
                        if not (kwargs.get('nomo', False) or message):
                            message = '{} "{}"'.format(_('Не заполнено обязательное поле'), 'nomo')
                        if not (kwargs.get('datumo', False) or message):
                            message = '{} "{}"'.format(_('Не заполнено обязательное поле'), 'datumo')

                        # Проверяем наличие записи с таким кодом
                        if not message:
                            if kwargs.get('tipo', False):
                                if kwargs.get('tipo').lower() not in Informoj.tipo_choices_nomo:
                                    message='{}: {}'.format(_('Неверное значение поля. Допустимые значения'), Informoj.tipo_choices_nomo)
                            else:
                                message = '{} "{}"'.format(_('Не заполнено обязательное поле'), 'tipo')


                        if not message:
                            if kwargs.get('enketo_id', False):
                                try:
                                    enketo = Enketo.objects.get(id=kwargs.get('enketo_id'), forigo=False,
                                                                arkivo=False, publikigo=True)
                                except Enketo.DoesNotExist:
                                    message = _('Неверный ID анкеты')
                            else:
                                message = '{} "{}"'.format(_('Не заполнено обязательное поле'), 'enketo_id')

                        if kwargs.get('forigo', False) and not message:
                            message = '{} "{}"'.format(_('При создании записи не допустимо указание поля'), 'forigo')

                        if kwargs.get('arkivo', False) and not message:
                            message = '{} "{}"'.format(_('При создании записи не допустимо указание поля'), 'arkivo')

                        # проверить JSON-поле на корректность ввода
                        if not message:
                            informoj = Informoj.objects.create(
                                enketo=enketo,
                                tipo=kwargs.get('tipo').lower(),
                                datumo=kwargs.get('datumo'),
                                forigo=False,
                                arkivo=False,
                                publikigo=kwargs.get('publikigo', False),
                                publikiga_dato=timezone.now()
                            )

                            set_enhavo(informoj.nomo, kwargs.get('nomo'), info.context.LANGUAGE_CODE)
                            if kwargs.get('priskribo', False):
                                set_enhavo(informoj.priskribo, kwargs.get('priskribo'), info.context.LANGUAGE_CODE)

                            informoj.save()

                            status = True
                            message = _('Запись создана')
                    else:
                        message = _('Недостаточно прав')
                else:
                    # Изменяем запись
                    if not (kwargs.get('nomo', False) or kwargs.get('enketo_id', False)
                            or kwargs.get('forigo', False) or kwargs.get('arkivo', False)
                            or kwargs.get('publikigo', False) or kwargs.get('priskribo', False)
                            or kwargs.get('tipo', False) or kwargs.get('datumo', False)):
                        message = _('Не задано ни одно поле для изменения')

                    if 'enketo_id' in kwargs and not message:
                        try:
                            enketo = Enketo.objects.get(id=kwargs.get('enketo_id'), forigo=False,
                                                        arkivo=False, publikigo=True)
                        except Enketo.DoesNotExist:
                            message = _('Неверный ID анкеты')

                    if not message:
                        # Ищем запись для изменения
                        try:
                            informoj = Informoj.objects.get(uuid=kwargs.get('uuid'), forigo=False)
                            if (not uzanto.has_perm('enketo.povas_forigi_enketo_informoj')
                                    and kwargs.get('forigo', False)):
                                message = _('Недостаточно прав для удаления')
                            elif not uzanto.has_perm('enketo.povas_shanghi_enketo_informoj'):
                                message = _('Недостаточно прав для изменения')
                            else:
                                
                                informoj.enketo = enketo or informoj.enketo
                                informoj.tipo = kwargs.get('tipo', informoj.tipo).lower()
                                informoj.forigo = kwargs.get('forigo', informoj.forigo)
                                informoj.foriga_dato = timezone.now() if kwargs.get('forigo', False) else None
                                informoj.arkivo = kwargs.get('arkivo', informoj.arkivo)
                                informoj.arkiva_dato = timezone.now() if kwargs.get('arkivo', False) else None
                                informoj.publikigo = kwargs.get('publikigo', informoj.publikigo)
                                informoj.publikiga_dato = timezone.now() if kwargs.get('publikigo', False) else None
                                informoj.datumo=kwargs.get('datumo', informoj.datumo)

                                if kwargs.get('nomo', False):
                                    set_enhavo(informoj.nomo, kwargs.get('nomo'), info.context.LANGUAGE_CODE)
                                if kwargs.get('priskribo', False):
                                    set_enhavo(informoj.priskribo, kwargs.get('priskribo'), info.context.LANGUAGE_CODE)

                                informoj.save()
                                status = True
                                message = _('Запись успешно изменена')
                        except Informoj.DoesNotExist:
                            message = _('Запись не найдена')
        else:
            message = _('Недостаточно прав')

        return RedaktuInformoj(status=status, message=message, informoj=informoj)


class RedaktuEnketi(graphene.Mutation):
    status = graphene.Boolean()
    message = graphene.String()
    enketi = graphene.Field(EnketiNode, description=_('Созданная/изменённая заполненной Анкеты'))

    class Arguments:
        uuid = graphene.UUID(description=_('UUID записи'))
        enketo_id = graphene.Int(description=_('ID анкеты'))
        forigo = graphene.Boolean(description=_('Признак удаления записи'))
        arkivo = graphene.Boolean(description=_('Признак архивной записи'))
        publikigo = graphene.Boolean(description=_('Признак опубликованной записи'))
        # параметры для создания полей данной анкеты (используется только при создании новой анкеты)
        informoj_kvanto = graphene.Int(description=_('Количество полей')) # kvanto - численность - для последующей проверки
        informoj_uuid = graphene.List(graphene.String,description=_('UUID полей заполняемой анкеты'))
        informoj_datumo = graphene.List(GenericScalar,description=_('Значение полей заполняемой анкеты'))

    @staticmethod
    def mutate(root, info, **kwargs):
        status = False
        message = None
        enketi = None
        enketo = None
        informoj = []
        uzanto = info.context.user

        if uzanto.is_authenticated:
            with transaction.atomic():
                # Создаём новую запись
                if not kwargs.get('uuid', False):
                    if uzanto.has_perm('enketo.povas_krei_enketi'):
                        # Проверяем наличие всех полей
                        if kwargs.get('forigo', False) and not message:
                            message = '{} "{}"'.format(_('При создании записи не допустимо указание поля'), 'forigo')

                        if kwargs.get('arkivo', False) and not message:
                            message = '{} "{}"'.format(_('При создании записи не допустимо указание поля'), 'arkivo')

                        # проверяем наличие полей анкеты
                        if kwargs.get('informoj_kvanto', False) and not message:
                            # проверяем наличие обязательных параметров
                            # проверяем соответствия количества полей анкеты переданной численности
                            if not message:
                                if kwargs.get('informoj_uuid', False):
                                    if kwargs.get('informoj_kvanto') != len(kwargs.get('informoj_uuid')):
                                        message = '{} "{}"'.format(_('Не совпадает количество полей переданного количества с '), 'informoj_uuid')
                                    else:
                                        # находим все поля, на которые даны ссылки
                                        for i in range(kwargs.get('informoj_kvanto')):
                                            try:
                                                informoj.append(Informoj.objects.get(uuid=kwargs.get('informoj_uuid')[i], forigo=False,
                                                                                     arkivo=False, publikigo=True))
                                            except Informoj.DoesNotExist:
                                                message = '{} "{}"'.format(_('Неверный ID анкеты'),kwargs.get('informoj_uuid')[i])
                                                break
                                else:
                                    message = '{} "{}"'.format(_('Не заполнено обязательное поле'), 'informoj_uuid')
                            if not message:
                                if kwargs.get('informoj_datumo', False):
                                    if kwargs.get('informoj_kvanto') != len(kwargs.get('informoj_datumo')):
                                        message = '{} "{}"'.format(_('Не совпадает количество полей переданного количества с '), 'informoj_datumo')
                                else:
                                    message = '{} "{}"'.format(_('Не заполнено обязательное поле'), 'informoj_datumo')

                        # проверяем наличие записей с таким кодом в списке
                        if not message:
                            if kwargs.get('enketo_id', False):
                                try:
                                    enketo = Enketo.objects.get(id=kwargs.get('enketo_id'), forigo=False,
                                                                arkivo=False, publikigo=True)
                                except Enketo.DoesNotExist:
                                    message = _('Неверный ID анкеты')
                            else:
                                message = '{} "{}"'.format(_('Не заполнено обязательное поле'), 'enketo_id')

                        if not message:
                            enketi = Enketi.objects.create(
                                autoro=uzanto,
                                enketo=enketo,
                                forigo=False,
                                arkivo=False,
                                publikigo=kwargs.get('publikigo', False),
                                publikiga_dato=timezone.now()
                            )

                            enketi.save()

                            # создаём поля анкеты
                            if kwargs.get('informoj_kvanto', False) and not message:
                                for i in range(kwargs.get('informoj_kvanto')):
                                    enketi_informoj = EnketiInformoj.objects.create(
                                        enketi=enketi,
                                        informoj=informoj[i],
                                        datumo=kwargs.get('informoj_datumo')[i],
                                        forigo=False,
                                        arkivo=False,
                                        publikigo=kwargs.get('publikigo', False),
                                        publikiga_dato=timezone.now()
                                    )

                                    enketi_informoj.save()

                            status = True
                            message = _('Запись создана')
                    else:
                        message = _('Недостаточно прав')
                else:
                    # Изменяем запись
                    if not (kwargs.get('enketo_id', False) 
                            or kwargs.get('forigo', False) or kwargs.get('arkivo', False)
                            or kwargs.get('publikigo', False)):
                        message = _('Не задано ни одно поле для изменения')

                    # проверяем наличие записей с таким кодом в списке
                    if 'enketo_id' in kwargs and not message:
                        try:
                            enketo = Enketo.objects.get(id=kwargs.get('enketo_id'), forigo=False,
                                                        arkivo=False, publikigo=True)
                        except Enketo.DoesNotExist:
                            message = _('Неверный ID анкеты')

                    # Ищем запись для изменения
                    if not message:
                        try:
                            enketi = Enketi.objects.get(uuid=kwargs.get('uuid'), forigo=False)
                            if (not uzanto.has_perm('enketo.povas_forigi_enketi')
                                    and kwargs.get('forigo', False)):
                                message = _('Недостаточно прав для удаления')
                            elif not uzanto.has_perm('enketo.povas_shanghi_enketi'):
                                message = _('Недостаточно прав для изменения')
                            else:

                                enketi.enketo = enketo or enketi.enketo
                                enketi.forigo = kwargs.get('forigo', enketi.forigo)
                                enketi.foriga_dato = timezone.now() if kwargs.get('forigo', False) else None
                                enketi.arkivo = kwargs.get('arkivo', enketi.arkivo)
                                enketi.arkiva_dato = timezone.now() if kwargs.get('arkivo', False) else None
                                enketi.publikigo = kwargs.get('publikigo', enketi.publikigo)
                                enketi.publikiga_dato = timezone.now() if kwargs.get('publikigo', False) else None
                                enketi.lasta_autoro = uzanto
                                enketi.lasta_dato = timezone.now()

                                enketi.save()
                                status = True
                                message = _('Запись успешно изменена')
                        except Enketi.DoesNotExist:
                            message = _('Запись не найдена')
        else:
            message = _('Требуется авторизация')

        return RedaktuEnketi(status=status, message=message, enketi=enketi)


class RedaktuEnketiInformoj(graphene.Mutation):
    status = graphene.Boolean()
    message = graphene.String()
    enketi_informoj = graphene.Field(EnketiInformojNode, description=_('Созданная/изменённая заполненных полей Анкеты'))

    class Arguments:
        uuid = graphene.UUID(description=_('UUID записи'))
        enketi_uuid = graphene.String(description=_('UUID заполняемой анкеты'))
        informoj_uuid = graphene.String(description=_('UUID поля заполняемой анкеты'))
        datumo = GenericScalar(description=_('Значение поля'))
        forigo = graphene.Boolean(description=_('Признак удаления записи'))
        arkivo = graphene.Boolean(description=_('Признак архивной записи'))
        publikigo = graphene.Boolean(description=_('Признак опубликованной записи'))

    @staticmethod
    def mutate(root, info, **kwargs):
        status = False
        message = None
        enketi_informoj = None
        enketi = None
        informoj = None
        uzanto = info.context.user

        if uzanto.is_authenticated:
            with transaction.atomic():
                # Создаём новую запись
                if not kwargs.get('uuid', False):
                    if uzanto.has_perm('enketo.povas_krei_enketi_informoj'):
                        # Проверяем наличие всех полей
                        if kwargs.get('forigo', False) and not message:
                            message = '{} "{}"'.format(_('При создании записи не допустимо указание поля'), 'forigo')

                        if kwargs.get('arkivo', False) and not message:
                            message = '{} "{}"'.format(_('При создании записи не допустимо указание поля'), 'arkivo')
                        if not (kwargs.get('datumo', False) or message):
                            message = '{} "{}"'.format(_('Не заполнено обязательное поле'), 'datumo')

                        # проверяем наличие записей с таким кодом в списке
                        if not message:
                            if kwargs.get('enketi_uuid', False):
                                try:
                                    enketi = Enketi.objects.get(uuid=kwargs.get('enketi_uuid'), forigo=False,
                                                                arkivo=False, publikigo=True)
                                except Enketi.DoesNotExist:
                                    message = _('Неверный ID анкеты')
                            else:
                                message = '{} "{}"'.format(_('Не заполнено обязательное поле'), 'enketo_id')

                        if not message:
                            if kwargs.get('informoj_uuid', False):
                                try:
                                    informoj = Informoj.objects.get(uuid=kwargs.get('informoj_uuid'), forigo=False,
                                                                    arkivo=False, publikigo=True)
                                except Informoj.DoesNotExist:
                                    message = _('Неверный ID анкеты')
                            else:
                                message = '{} "{}"'.format(_('Не заполнено обязательное поле'), 'informoj_uuid')

                        if not message:
                            enketi_informoj = EnketiInformoj.objects.create(
                                enketi=enketi,
                                informoj=informoj,
                                datumo=kwargs.get('datumo'),
                                forigo=False,
                                arkivo=False,
                                publikigo=kwargs.get('publikigo', False),
                                publikiga_dato=timezone.now()
                            )

                            enketi_informoj.save()

                            status = True
                            message = _('Запись создана')
                    else:
                        message = _('Недостаточно прав')
                else:
                    # Изменяем запись
                    if not (kwargs.get('enketi_uuid', False) or kwargs.get('informoj_uuid', False) 
                            or kwargs.get('forigo', False) or kwargs.get('arkivo', False)
                            or kwargs.get('publikigo', False) or kwargs.get('datumo', False)):
                        message = _('Не задано ни одно поле для изменения')

                    # проверяем наличие записей с таким кодом в списке
                    if 'enketi_uuid' in kwargs and not message:
                        try:
                            enketi = Enketi.objects.get(uuid=kwargs.get('enketi_uuid'), forigo=False,
                                                        arkivo=False, publikigo=True)
                        except Enketi.DoesNotExist:
                            message = _('Неверный UUID заполняемой анкеты')

                    if 'informoj_uuid' in kwargs and not message:
                        try:
                            informoj = Informoj.objects.get(uuid=kwargs.get('informoj_uuid'), forigo=False,
                                                        arkivo=False, publikigo=True)
                        except Informoj.DoesNotExist:
                            message = _('Неверный UUID поля заполняемой анкеты')

                    # Ищем запись для изменения
                    if not message:
                        try:
                            enketi_informoj = EnketiInformoj.objects.get(uuid=kwargs.get('uuid'), forigo=False)
                            if (not uzanto.has_perm('enketo.povas_forigi_enketi_informoj')
                                    and kwargs.get('forigo', False)):
                                message = _('Недостаточно прав для удаления')
                            elif not uzanto.has_perm('enketo.povas_shanghi_enketi_informoj'):
                                message = _('Недостаточно прав для изменения')
                            else:

                                enketi_informoj.enketi = enketi or enketi_informoj.enketi
                                enketi_informoj.informoj = informoj or enketi_informoj.informoj
                                enketi_informoj.forigo = kwargs.get('forigo', enketi_informoj.forigo)
                                enketi_informoj.foriga_dato = timezone.now() if kwargs.get('forigo', False) else None
                                enketi_informoj.arkivo = kwargs.get('arkivo', enketi_informoj.arkivo)
                                enketi_informoj.arkiva_dato = timezone.now() if kwargs.get('arkivo', False) else None
                                enketi_informoj.publikigo = kwargs.get('publikigo', enketi_informoj.publikigo)
                                enketi_informoj.publikiga_dato = timezone.now() if kwargs.get('publikigo', False) else None
                                enketi_informoj.datumo=kwargs.get('datumo', enketi_informoj.datumo)

                                enketi_informoj.save()
                                status = True
                                message = _('Запись успешно изменена')
                        except EnketiInformoj.DoesNotExist:
                            message = _('Запись не найдена')
        else:
            message = _('Требуется авторизация')

        return RedaktuEnketiInformoj(status=status, message=message, enketi_informoj=enketi_informoj)


class EnketoMutations(graphene.ObjectType):
    redaktu_enketo_tipo = RedaktuEnketoTipo.Field(
        description=_('''Создаёт или редактирует типы анкет''')
    )
    redaktu_enketo = RedaktuEnketo.Field(
        description=_('''Создаёт или редактирует Анкеты''')
    )
    redaktu_enketo_informoj = RedaktuInformoj.Field(
        description=_('''Создаёт или редактирует поля Анкет''')
    )
    redaktu_enketo_enketi = RedaktuEnketi.Field(
        description=_('''Создаёт или редактирует заполненные Анкеты''')
    )
    redaktu_enketo_enketi_informoj = RedaktuEnketiInformoj.Field(
        description=_('''Создаёт или редактирует заполненные поля Анкет''')
    )

